<?php
/**
 * 易优CMS
 * ============================================================================
 * 版权所有 2016-2028 海南赞赞网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.eyoucms.com
 * ----------------------------------------------------------------------------
 * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
 * ============================================================================
 * Author: 陈风任 <491085389@qq.com>
 * Date: 2022-03-10
 */

namespace app\api\model\v1;

use think\Db;
use think\Cache;
use Grafika\Color;
use Grafika\Grafika;

require_once './../vendor/grafika/src/autoloader.php';

/**
 * 微信小程序商品海报模型
 */
load_trait('controller/Jump');

class Poster extends Base
{
    use \traits\controller\Jump;

    //初始化
    protected function initialize()
    {
        // 需要调用`Model`的`initialize`方法
        parent::initialize();

        $this->aid = 0;
        $this->product = []; //产品详情数据
        $this->post_data = [];
        $this->poster_path = ''; // 保存目录
        $this->poster_img = ''; //背景图片
        $this->applets_qrcode = []; //二维码
    }

    // 商品海报生成处理
    public function GetCreateGoodsShareQrcodePoster($post = [])
    {
        // 商品ID
        $this->aid = $post['aid'];
        // 图片、海报保存目录
        $this->poster_path = UPLOAD_PATH . 'tmp/poster_' . $this->aid . '/';
        // 背景图片处理
        $this->poster_img = './'.PUBLIC_PATH.'static/common/images/product-bg.png';

        // 获取商品信息
        $this->product = $this->GetProductData();

        // 生成小程序二维码需携带参数
        $page = 'pages/product/detail';
        $scene = 'goodsID=' . $this->aid;
        $width = '280';
        $this->post_data = compact('page', 'scene', 'width');

        // 小程序二维码处理
        $this->applets_qrcode = $this->GetAppletsQrcode();

        // 组合并返回商品分享海报图片
        return $this->GetProductSharePosterImage();
    }

    // 返回已处理的商品信息
    private function GetProductData()
    {
        // 查询商品信息
        $where['aid'] = $this->aid;
        $field = 'aid, title, litpic, users_price, seo_description';
        $product = Db::name("archives")->where($where)->field($field)->find();

        if (!empty($product)) {
            $product['users_price_arr'] = explode('.', $product['users_price']);
            // 商品图片处理
            $productLitpic = $this->get_default_pic($product['litpic'], true);
            // 保存图片的完整路径
            $LitpicSavePath = $this->poster_path . 'product_' . md5($this->aid) . '.png';
            // 若文件夹不存在则创建
            !is_dir($this->poster_path) && tp_mkdir($this->poster_path);

            // 图片保存到文件处理
            $ch = curl_init($productLitpic);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
            // https请求 不验证证书和hosts
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);   //重要,源文件链接带https的话就必须使用
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);

            $img = curl_exec($ch);
            curl_close($ch);
            $fp = fopen($LitpicSavePath, 'w');
            fwrite($fp, $img);
            fclose($fp);
            // 返回数据
            $product['litpic'] = $LitpicSavePath;

            return $product;
        } else {
            $this->error('商品不存在');
        }
    }

    // 返回已处理的小程序二维码
    private function GetAppletsQrcode()
    {
        // 保存图片的完整路径
        $QrcodeSavePath = $this->poster_path . 'qrcode_' . md5($this->aid) . '.png';

        // 若文件夹不存在则创建
        !is_dir($this->poster_path) && tp_mkdir($this->poster_path);

        // 是否配置小程序信息
        $AppletsSetting = $this->GetWeChatAppletsSetting();
        if (empty($AppletsSetting['status'])) $this->error($AppletsSetting['prompt']);

        // 调用微信接口查询小程序AccessToken
        $AppletsToken = getWeixinAccessToken();

        if (empty($AppletsToken['code'])) $this->error($AppletsToken['msg']);
        // 调用微信接口获取小程序二维码
        return $this->GetWeChatAppletsQrcode($AppletsToken['access_token'], $QrcodeSavePath);
    }

    // 返回微信小程序配置信息
    private function GetWeChatAppletsSetting()
    {
        $inc = tpSetting("OpenMinicode.conf_weixin");
        $inc = json_decode($inc, true);

        // 处理返回小程序配置
        if (!empty($inc['appid'])) {
            $AppletsSetting = [
                'status' => true,
                'values' => $inc,
            ];
        } else {
            $AppletsSetting = [
                'status' => false,
                'prompt' => '请先配置并发布小程序再生成分销商二维码',
            ];
        }

        return $AppletsSetting;
    }

    // 返回微信小程序商品详情页二维码
    private function GetWeChatAppletsQrcode($AccessToken = null, $QrcodeSavePath = null)
    {
        // 获取微信小程序二维码
        $PostUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $AccessToken;
        $AppletsQrcode = httpRequest($PostUrl, 'POST', json_encode($this->post_data, JSON_UNESCAPED_UNICODE));
        $is_fail = strpos($AppletsQrcode, "errcode");
        // 保存图片，保存成功则返回图片路径
        if ($is_fail != false) {   //报错
            $error_msg = json_decode($AppletsQrcode, true);
            $data = [
                'status' => false,
                'errcode' => $error_msg['errcode'],
                'errmsg' => '获取二维码失败，' . $error_msg['errcode'] . ":" . $error_msg['errmsg'],
            ];
        } else if (@file_put_contents($QrcodeSavePath, $AppletsQrcode)) {
            $data = [
                'status' => true,
                'qrcode' => $QrcodeSavePath,
            ];
        } else {
            $data = [
                'status' => false,
                'errcode' => 10000,
                'errmsg' => '获取二维码失败，请重试',
            ];
        }

        return $data;
    }

    // 返回商品分享海报图片
    private function GetProductSharePosterImage()
    {
        $product = $this->product;
        $Grafika = new Grafika;
        $editor = $Grafika::createEditor(['Gd']);
        // 打开海报背景图
        $editor->open($backdropImage, $this->poster_img);
        // 打开商品图片
        $editor->open($roduct_litpic, $product['litpic']);
        // 重设商品图片宽高
        $editor->resizeExact($roduct_litpic, 520, 520);
        // 商品图片添加到背景图
        $editor->blend($backdropImage, $roduct_litpic, 'normal', 1.0, 'top-left', 30, 27);

        // 字体文件路径
//        $fontPath = Grafika::fontsDir() . '/' . 'st-heiti-light.ttc';
        $fontPath = Grafika::fontsDir() . '/' . 'HanaMeatball-Medium-2.ttf';

        // 商品名称处理换行
        $fontSize = 24;
        $product_name = $this->wrapText($fontSize, 0, $fontPath, $product['title'], 530, 2);
        // 写入商品名称
        $editor->text($backdropImage, $product_name, $fontSize, 30, 574, new Color('#000'), $fontPath);

        //写入商品价格
        $p_box = imagettfbbox(30, 1, $fontPath, $product['users_price_arr'][0]);
        $min_x = min([$p_box[0], $p_box[2], $p_box[4], $p_box[6]]);
        $max_x = max([$p_box[0], $p_box[2], $p_box[4], $p_box[6]]);
        $p_x = 63 + ($max_x - $min_x);

        $rmb = $this->wrapText(20, 0, $fontPath, '￥', 350, 1);
        $editor->text($backdropImage, $rmb, 20, 31, 687, new Color('#ff0000'), $fontPath);

        $editor->text($backdropImage, $product['users_price_arr'][0], 30, 55, 678, new Color('#ff4444'));
        $editor->text($backdropImage, '.'.$product['users_price_arr'][1], 20, $p_x, 687, new Color('#ff4444'));

        $web = tpCache('web');
        $minipro_name = $this->wrapText(24, 0, $fontPath, $web['web_name'], 350, 1);
        $editor->text($backdropImage, $minipro_name, 26, 31, 760, new Color('#000'), $fontPath);

        $tiyan = $this->wrapText(16, 0, $fontPath, '长按识别 · 立即体验', 350, 1);
        // 写入商品名称
        $editor->text($backdropImage, $tiyan, 18, 31, 822, new Color('#000'), $fontPath);

        // 打开小程序码
        if (!empty($this->applets_qrcode['status'])) {
            $editor->open($qrcodeImage, $this->applets_qrcode['qrcode']);
            // 重设小程序码宽高
            $editor->resizeExact($qrcodeImage, 150, 150);
            // 小程序码添加到背景图
            $editor->blend($backdropImage, $qrcodeImage, 'normal', 1, 'top-left', 391, 726);

//            // 重设小程序码宽高
//            $editor->resizeExact($HeadPic, 54, 54);
//            // 小程序码添加到背景图
//            $editor->blend($backdropImage, $HeadPic, 'normal', 1, 'top-left', 25, 671.5);

            // 保存商品海报
//            $posterImageName = 'product_poster_' . md5($this->aid.getTime()) . '.png';
            $posterImageName = 'product_poster_' . $this->aid . '.png';
            $posterImagePath = $this->poster_path . $posterImageName;
            $editor->save($backdropImage, $posterImagePath);

            // 返回商品海报
            $posterImagePath = request()->domain() . ROOT_DIR . '/' . $posterImagePath;
            return [
                'name' => $posterImageName,
                'path' => $this->poster_path,
                'poster' => $posterImagePath
            ];
        } else {
            return $this->applets_qrcode;
        }

    }

    // 处理文字超出长度自动换行
    private function wrapText($fontsize, $angle, $fontface, $string, $width, $max_line = null)
    {
        // 这几个变量分别是 字体大小, 角度, 字体名称, 字符串, 预设宽度
        $content = "";
        // 将字符串拆分成一个个单字 保存到数组 letter 中
        $letter = [];
        for ($i = 0; $i < mb_strlen($string, 'UTF-8'); $i++) {
            $letter[] = mb_substr($string, $i, 1, 'UTF-8');
        }
        $line_count = 0;
        foreach ($letter as $l) {
            $testbox = imagettfbbox($fontsize, $angle, $fontface, $content . ' ' . $l);
            // 判断拼接后的字符串是否超过预设的宽度
            if (($testbox[2] > $width) && ($content !== "")) {
                $line_count++;
                if ($max_line && $line_count >= $max_line) {
                    $content = mb_substr($content, 0, -1, 'UTF-8') . "...";
                    break;
                }
                $content .= "\n";
            }
            $content .= $l;
        }
        return $content;
    }
}